﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Windows;
using System.Windows.Media.Animation;
using WWLauncher.Constant;
using WWLauncher.ViewModel;

namespace WWLauncher.Util
{

    enum HideType
    {
        TopShow = 1,
        LeftShow = 2,
        RightShow = 3,
        TopHide = 4,
        LeftHide = 5,
        RightHide = 6
    }

    /// <summary>
    /// 边距隐藏处理
    /// </summary>
    public class AutoHidden: IDisposable
    {
        private Window ParentWindow { get; set; }
        private DebugConfig DebugConfig { get; }

        private const int hideTime = 20;
        private const int showTime = 20;
        private int _animalTime;
        private const int fadeHideTime = 50;
        private const int fadeShowTime = 50;
        private const double showMarginWidth = 1;
        /// <summary>
        /// 贴边隐藏后  以非鼠标经过方式触发显示
        /// </summary>
        public bool MarginHideAndOtherShow { set; get; }
        public bool WindowClosing { get; set; }
        /// <summary>
        /// 正在隐藏
        /// </summary>
        public bool OnHide { get; set; }
        /// <summary>
        /// 是否隐藏
        /// </summary>
        public bool IsHide { get; set; }

        private readonly System.Windows.Forms.Timer _timer;

        public AutoHidden(Window window)
        {
            ParentWindow = window;
            DebugConfig = MainViewModel.Instance().AppConfig.DebugConfig;
            _timer = new System.Windows.Forms.Timer
            {
                Interval = 200
            };
            _timer.Tick += WorkingHandler;
        }

        /// <summary>
        /// 窗体是否贴边
        /// </summary>
        /// <returns></returns>
        public bool IsMargin()
        {
            double screenLeft = SystemParameters.VirtualScreenLeft;
            double screenTop = SystemParameters.VirtualScreenTop;
            double screenWidth = SystemParameters.VirtualScreenWidth;

            double windowTop = ParentWindow.Top;
            double windowLeft = ParentWindow.Left;
            double windowWidth = ParentWindow.Width;

            //窗体是否贴边
            return (windowLeft <= screenLeft
                || windowTop <= screenTop
                || windowLeft + windowWidth + Math.Abs(screenLeft) >= screenWidth);
        }



        #region 窗体贴边隐藏功能
        /// <summary>
        /// 窗体贴边隐藏功能
        /// </summary>
        /// <param name="o"></param>
        /// <param name="e"></param>
        private void WorkingHandler(object o, EventArgs e)
        {
            if (RunTimeStatus.WpfWindowOpening) { return; }

            if (this.MarginHideAndOtherShow || RunTimeStatus.LockAppPanel)
                return;

            //有全屏化应用则不显示
            if (ScreenUtil.IsPrimaryFullScreen())
            {
                return;
            }

            double screenTop = SystemParameters.VirtualScreenTop;
            double screenLeft = SystemParameters.VirtualScreenLeft;
            double screenWidth = SystemParameters.VirtualScreenWidth;

            double windowHeight = ParentWindow.Height;
            double windowWidth = ParentWindow.Width;

            double windowTop = ParentWindow.Top;
            double windowLeft = ParentWindow.Left;

            //获取鼠标位置
            System.Windows.Point p = MouseUtil.GetMousePosition();
            //p.X -= 10;
            //p.Y -= 10;
            var bounds = ParentWindow.RestoreBounds.Contains(p);

            //鼠标不在窗口上
            if (!bounds && !IsHide)
            {
                //左上角
                if ((windowTop <= screenTop) && (windowLeft <= screenLeft))
                {
                    IsHide = true;
                    ParentWindow.Top = windowHeight * -1;
                    ParentWindow.Left = windowWidth * -1;
                    return;
                }
                //右上角
                if ((windowTop <= screenTop) && (windowLeft + windowWidth + Math.Abs(screenLeft) >= screenWidth))
                {
                    IsHide = true;
                    ParentWindow.Top = ParentWindow.Height * -1;
                    ParentWindow.Left = screenWidth + windowWidth - showMarginWidth;
                }
                //上方隐藏条件
                if (windowTop <= screenTop)
                {
                    IsHide = true;

                    HideAnimation(windowTop, screenTop - windowHeight + showMarginWidth, HideType.TopHide);
                    return;
                }
                //左侧隐藏条件
                if (windowLeft <= screenLeft)
                {
                    IsHide = true;

                    HideAnimation(windowLeft, screenLeft - windowWidth + showMarginWidth, HideType.LeftHide);
                    return;
                }
                //右侧隐藏条件
                if (windowLeft + windowWidth + Math.Abs(screenLeft) >= screenWidth)
                {
                    IsHide = true;

                    HideAnimation(windowLeft, screenWidth - Math.Abs(screenLeft) - showMarginWidth, HideType.RightHide);

                    return;
                }
            }
            else if (bounds && IsHide)
            {
                ParentWindow.Show();

                //左上角
                if ((windowTop <= screenTop - showMarginWidth) && (windowLeft <= screenLeft - showMarginWidth))
                {
                    IsHide = false;
                    ParentWindow.Top = 0;
                    ParentWindow.Left = 0;
                    return;
                }
                //右上角,不起作用
                if ((windowTop <= screenTop - showMarginWidth)
                    && (windowLeft + Math.Abs(screenLeft) - showMarginWidth >= screenWidth))
                {
                    IsHide = false;
                    ParentWindow.Top = 0;
                    //ParentWindow.Left = screenWidth - Math.Abs(screenLeft) - windowWidth;
                    return;
                }
                //上方显示
                if (windowTop <= screenTop - showMarginWidth)
                {
                    IsHide = false;
                    HideAnimation(windowTop, screenTop, HideType.TopShow);

                    return;
                }

                //左侧显示
                if (windowLeft <= screenLeft - showMarginWidth)
                {
                    IsHide = false;
                    HideAnimation(windowLeft, screenLeft, HideType.LeftShow);

                    return;
                }

                //右侧显示
                if (windowLeft + Math.Abs(screenLeft) - showMarginWidth <= screenWidth)
                {
                    IsHide = false;
                    HideAnimation(windowLeft, screenWidth - Math.Abs(screenLeft) - windowWidth, HideType.RightShow);

                    return;
                }
            }
        }
        #endregion 


        public void StartHide()
        {
            OnHide = true;
            _timer.Start();
        }

        public void StopHide()
        {
            OnHide = false;
            _timer.Stop();

            if (WindowClosing) { return; }

            //功能关闭 如果界面是隐藏状态  那么要显示界面 ↓
            if (IsHide)
            {
                double screenLeft = SystemParameters.VirtualScreenLeft;
                double screenTop = SystemParameters.VirtualScreenTop;
                double screenWidth = SystemParameters.VirtualScreenWidth;

                double windowWidth = ParentWindow.Width;
                double windowTop = ParentWindow.Top;
                double windowLeft = ParentWindow.Left;

                ParentWindow.Show();

                //左侧显示
                if (windowLeft <= screenLeft - showMarginWidth)
                {
                    IsHide = false;

                    HideAnimation(windowLeft, screenLeft, HideType.LeftShow);
                    return;
                }

                //上方显示
                if (windowTop <= screenTop - showMarginWidth)
                {
                    IsHide = false;

                    HideAnimation(windowTop, screenTop, HideType.TopShow);
                    return;
                }

                //右侧显示
                if (windowLeft + Math.Abs(screenLeft) - showMarginWidth <= screenWidth)
                {
                    IsHide = false;

                    HideAnimation(windowLeft, screenWidth - Math.Abs(screenLeft) - windowWidth, HideType.RightShow);
                    return;
                }
            }
        }


        private void HideAnimation(double from, double to, HideType hideType)
        {
            dynamic ppp =
                new
                {
                    HideType = hideType.ToString(),
                    From = from,
                    To = to
                };
            LogUtil.WriteLog(JsonSerializer.Serialize(ppp));
            new Thread(() =>
            {
                switch (hideType)
                {
                    case HideType.LeftShow:
                        to -= 20;
                        break;
                    case HideType.RightShow:
                        to += 20;
                        break;
                    case HideType.TopShow:
                        to -= 20;
                        break;
                }

                double abs = Math.Abs(Math.Abs(to) - Math.Abs(from));

                if (hideType <= HideType.RightShow)
                {
                    _animalTime = showTime;
                }
                else
                {
                    _animalTime = hideTime;
                }
                double subLen = abs / _animalTime;

                int count = 0;
                while (count < _animalTime)
                {
                    ParentWindow.Dispatcher.Invoke(() =>
                    {
                        switch (hideType)
                        {
                            case HideType.LeftHide:
                                ParentWindow.Left -= subLen;
                                break;
                            case HideType.LeftShow:
                                ParentWindow.Left += subLen;
                                break;
                            case HideType.RightHide:
                                ParentWindow.Left += subLen;
                                break;
                            case HideType.RightShow:
                                ParentWindow.Left -= subLen;
                                break;
                            case HideType.TopHide:
                                ParentWindow.Top -= subLen;
                                break;
                            case HideType.TopShow:
                                ParentWindow.Top += subLen;
                                break;
                        }
                    });
                    count++;
                    Thread.Sleep(1);
                }

                ParentWindow.Dispatcher.Invoke(() =>
                {
                    switch (hideType)
                    {
                        case HideType.TopHide:
                            ParentWindow.Top = to;
                            break;
                        case HideType.TopShow:
                            ParentWindow.Top = to;
                            break;
                        default:
                            ParentWindow.Left = to;
                            break;
                    }
                    if (hideType == HideType.LeftHide || hideType == HideType.RightHide || hideType == HideType.TopHide)
                    {
                        ParentWindow.Hide();
                    }
                    if (hideType == HideType.LeftShow || hideType == HideType.RightShow || hideType == HideType.TopShow)
                    {
                        ParentWindow.Show();
                    }
                });
            }).Start();
        }


        public void WaitHide(int waitTime, Action value)
        {
            if (value != null)
                value.Invoke();
            Thread t = new Thread(() =>
            {
                Thread.Sleep(waitTime);
                //修改状态为false 继续执行贴边隐藏
                this.MarginHideAndOtherShow = false;
            })
            {
                IsBackground = true
            };
            t.Start();
        }

        public void Dispose()
        {
            
        }
    }
}